StorageRbacService.getGrants   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
c 0
b 0
f 0
rs 10
cc 1
1
import { Inject, Injectable, Optional } from '@nestjs/common';
2
import { IStorageRbac } from '../interfaces/storage.rbac.interface';
3
import { IDynamicStorageRbac } from '../interfaces/dynamic.storage.rbac.interface';
4
import { ICacheRBAC } from '../interfaces/cache.rbac.interface';
5
import { Ctr } from '../ctr/ctr';
6
7
@Injectable()
8
export class StorageRbacService {
9
    constructor(
10
        @Inject('IDynamicStorageRbac')
11
        private readonly rbac: IDynamicStorageRbac,
12
        @Optional() @Inject('ICacheRBAC')
13
        private readonly cache?: ICacheRBAC,
14
    ) {
15
16
    }
17
18
    async getStorage(): Promise<IStorageRbac> {
19
        return await this.rbac.getRbac();
20
    }
21
22
    async getPermissions(): Promise<object> {
23
        return (await this.rbac.getRbac()).permissions;
24
    }
25
26
    async getGrants(): Promise<object> {
27
        return (await this.rbac.getRbac()).grants;
28
    }
29
30
    async getRoles(): Promise<string[]> {
31
        return (await this.rbac.getRbac()).roles;
32
    }
33
34
    async getGrant(role: string): Promise<string[]> {
35
        const grant: object = await this.parseGrants();
36
37
        return grant[role] || [];
38
    }
39
40
    async getFilters(): Promise<object> {
41
        const result: any = {};
42
        const filters = (await this.getStorage()).filters;
43
        /* tslint:disable */
44
        for (const key in filters) {
45
            let filter;
46
            try {
47
                filter = Ctr.ctr.get(filters[key]);
48
            } catch (e) {
49
                filter = await Ctr.ctr.create(filters[key]);
50
            }
51
            result[key] = filter;
52
        }
53
54
        return result;
55
    }
56
57
    private async parseGrants(): Promise<object> {
58
59
        if (this.cache) {
60
            const cache = await this.getFromCache();
61
            if (cache) {
62
63
                return cache;
64
            }
65
        }
66
67
        const {grants, permissions} = await this.rbac.getRbac();
68
        const result = {};
69
        Object.keys(grants).forEach((key) => {
70
            const grant = grants[key];
71
72
            result[key] = [
73
                // remove duplicate
74
                ...new Set(
75
                    // get extended
76
                    grant.filter((value: string) => !value.startsWith('&')),
77
                ),
78
            ]
79
                // remove not existed
80
                .filter((value: string) => {
81
                    if (value.includes('@')) {
82
                        const spilt = value.split('@');
83
                        if (!permissions[spilt[0]]) {
84
                            return false;
85
                        }
86
87
                        return permissions[spilt[0]].some((inAction) => inAction === spilt[1]);
88
                    }
89
                    if (permissions[value]) {
90
                        return permissions[value];
91
                    }
92
93
                });
94
95
        });
96
        const findExtendedGrants = {};
97
        Object.keys(grants).forEach((key) => {
98
            const grant = grants[key];
99
100
            findExtendedGrants[key] = [
101
                // remove duplicate
102
                ...new Set(
103
                    // get extended
104
                    grant.filter((value: string) => {
105
                        if (value.startsWith('&')) {
106
                            const subGrant = value.substr(1);
107
                            if (grants[value.substr(1)] && subGrant !== key) {
108
                                return true;
109
                            }
110
                        }
111
                        return false;
112
                    }).map(value => value.substr(1)),
113
                ),
114
            ];
115
        });
116
117
        Object.keys(findExtendedGrants).forEach((key) => {
118
            const grant = findExtendedGrants[key];
119
120
            grant.forEach((value) => {
121
                result[key] = [...new Set([...result[key], ...result[value]])];
122
            });
123
124
        });
125
126
        Object.keys(result).forEach((key) => {
127
            const grant = result[key];
128
129
            const per = [];
130
            grant.forEach((value) => {
131
                if (!value.includes('@')) {
132
                    per.push(...permissions[value].map((dd) => {
133
                        return `${value}@${dd}`;
134
                    }));
135
                }
136
            });
137
138
            result[key] = [...new Set([...result[key], ...per])];
139
140
        });
141
142
        if (this.cache) {
143
            this.setIntoCache(result);
144
        }
145
146
        return result;
147
    }
148
149
    private async getFromCache(): Promise<object | null> {
150
        return this.cache.get();
151
    }
152
153
    private async setIntoCache(value: object): Promise<void> {
154
        await this.cache.set(value);
155
    }
156
}
157